package com.poem.springboot_rear.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.poem.springboot_rear.common.LogAs;
import com.poem.springboot_rear.common.LogType;
import com.poem.springboot_rear.common.Result;
import com.poem.springboot_rear.entity.ChargingDevice;
import com.poem.springboot_rear.service.ChargingDeviceService;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 功能：
 * 作者： 小祝小祝
 * 日期： 2023/11/20 12:55
 */
@CrossOrigin
@RestController
@RequestMapping("/chargingDevice")
public class ChargingDeviceController {

    @Resource
    ChargingDeviceService chargingDeviceService;

    /**
     * 新增充电宝信息
     */
    @LogAs(operation = "新增充电宝信息", type = LogType.ADD)
    @PostMapping("/add")
    public Result add(@RequestBody ChargingDevice chargingDevice) {
        try {
            chargingDeviceService.save(chargingDevice);
        } catch (Exception e) {
            if (e instanceof DuplicateKeyException) {
                return Result.error("插入数据库错误");
            } else {
                return Result.error("系统错误");
            }
        }
        return Result.success();
    }

    /**
     * 修改充电宝信息
     */
    @LogAs(operation = "修改充电宝信息", type = LogType.UPDATE)
    @PostMapping("/update")
    public Result update(@RequestBody ChargingDevice chargingDevice) {
        try {
            chargingDeviceService.updateById(chargingDevice);
        } catch (Exception e) {
            if (e instanceof DuplicateKeyException) {
                return Result.error("插入数据库错误");
            } else {
                return Result.error("系统错误");
            }
        }
        return Result.success();
    }

    /**
     * 删除充电宝信息（单个）
     *
     * @PathVariable 接收附带的ID
     */
    @LogAs(operation = "删除充电宝信息", type = LogType.DELETE)
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Integer id) {
        chargingDeviceService.removeById(id);
        return Result.success();
    }

    /**
     * 批量删除充电宝信息
     */
    @LogAs(operation = "批量删除充电宝信息", type = LogType.BATCH_DELETE)
    @DeleteMapping("/delete/batch")
    public Result batchDelete(@RequestBody List<Integer> ids) {
        chargingDeviceService.removeBatchByIds(ids);
        return Result.success();
    }

    /**
     * 查询充电宝信息（单个）
     */
    @GetMapping("/selectById/{id}")
    public Result selectById(@PathVariable Integer id) {
        chargingDeviceService.getById(id);
        return Result.success();
    }

    /**
     * 分页模糊查询充电宝信息
     * 根据brand model 分页模糊查询充电宝信息
     * pageIndex 当前页码
     * pageSize 每页多少行数据
     */
    @GetMapping("/selectByPage")
    public Result selectByPage(@RequestParam Integer pageIndex,
                               @RequestParam Integer pageSize,
                               @RequestParam String brand,
                               @RequestParam String model) {
        // 创建一个条件构造器
        QueryWrapper<ChargingDevice> queryWrapper = new QueryWrapper<ChargingDevice>().orderByDesc("id");
        queryWrapper.like(StrUtil.isNotBlank(brand), "brand", brand);
        queryWrapper.like(StrUtil.isNotBlank(model), "model", model);
        Page<ChargingDevice> page = chargingDeviceService.page(new Page<>(pageIndex, pageSize), queryWrapper);
        return Result.success(page);
    }

    /**
     * 批量导出数据
     * 当brand和model有值的时候就以他们搜索的内容导出
     * (required = false)表示这个字段可以不传入
     */
    @GetMapping("/export")
    public void exportData(@RequestParam(required = false) String brand,
                           @RequestParam(required = false) String model,
                           @RequestParam(required = false) String ids,
                           HttpServletResponse response) throws IOException {
        // 通过hutool工具创建writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        List<ChargingDevice> list;
        // 创建一个条件构造器
        QueryWrapper<ChargingDevice> queryWrapper = new QueryWrapper<>();
        // 如果ids 不为空
        if (StrUtil.isNotBlank(ids)) {
            // 第二种 根据多选的数据导出
            // ["1","2","3"]  => [1,2,3]  Arrays.stream把字符串数组转换为int数组
            // 把字符串数组使用split分割，然后组成一个map集合，然后再把map集合转为list数组
            List<String> idsArr1 = Arrays.stream(ids.split(",")).map(String::valueOf).collect(Collectors.toList());
            // in传入一个数据库字段名称
            // 查询数据库里id 的字段有没有idsArr1传过来的id，也就是我们在前端选中的行的id，如果有说明这个条件生效了
            // 或者就是说，把传过来的id在数据库进行查询，如果有就存储下来，没有就算了
            queryWrapper.in("id", idsArr1);
        } else {
            // 全部导出
            queryWrapper.like(StrUtil.isNotBlank(brand), "brand", brand);
            queryWrapper.like(StrUtil.isNotBlank(model), "model", model);
        }
        list = chargingDeviceService.list(queryWrapper);
        writer.write(list, true);

        // 设置文件头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        // attachment以附件的形式下载  设置文件名，编码格式，文件后缀
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("充电宝信息", "UTF-8") + ".xlsx");
        ServletOutputStream outputStream = response.getOutputStream();
        // 刷新然后关闭
        writer.flush(outputStream, true);
        writer.close();
        // 仅仅刷新缓冲区(一般写字符时用到,因为写字符时先进入缓冲区),然后将内存中的数据立刻写出(因为缓冲区是写满之后才会写出, 用flush()就不必等到缓冲区满,立刻写出)流对象还可以继续使用.
        outputStream.flush();
        // 关闭流对象. 关闭之后,流对象不可以继续使用.但是在关闭之前会刷新一次缓冲区.
        outputStream.close();
    }

    /**
     * 批量导入数据
     */
    @PostMapping("/import")
    public Result importData(MultipartFile file) throws IOException {
        // 获取流,并把流写到reader中去
        ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
        // 通过reader.readAll读出所有的数据
        List<ChargingDevice> list = reader.readAll(ChargingDevice.class);
        // 写入数据到数据库
        try {
            chargingDeviceService.saveBatch(list);
        } catch (Exception e) {
            e.printStackTrace(); // 打印错误信息
            return Result.error("数据导入错误,请确认格式正确");
        }
        return Result.success();
    }


}
